package com.yi.mall.goods.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.yi.mall.common.model.Category;
import com.yi.mall.goods.mapper.CategoryMapper;
import com.yi.mall.common.model.DTO.CategoryDTO;
import com.yi.mall.goods.service.ICategoryService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 商品类目 服务实现类
 * </p>
 *
 * @author zzy
 * @since 2025-07-10
 */
@Service
public class CategoryServiceImpl extends ServiceImpl<CategoryMapper, Category> implements ICategoryService {
    public List<CategoryDTO> listAll() {
        // 1 查询一级类目
        // 1.1 创建条件构造器
        LambdaQueryChainWrapper<Category> oneWrapper = new LambdaQueryChainWrapper<>(this.getBaseMapper());
        // 1.2 查询数据
        List<Category> ones = oneWrapper.isNull(Category::getParentId).list();
        // 2 查询二级类目
        // 2.1 创建条件构造器
        LambdaQueryChainWrapper<Category> twoWrapper = new LambdaQueryChainWrapper<>(this.getBaseMapper());
        // 2.2 查询数据
        // 2.2.1 获取一级类目id
        /**
         * map(Function)
         * 将流中的每个元素转换为另一种形式，产生新流。
         * 也就是说map会遍历ones的每个对象
         */
        List<Integer> oneIds = ones.stream().map(Category::getId).collect(Collectors.toList());
        // 2.2.2 查询二级类目(每一个一级类别下的二级类别)
        List<Category> twos = twoWrapper.in(Category::getParentId, oneIds).list();
        // 3 查询三级类目
        // 3.1 创建条件构造器
        LambdaQueryChainWrapper<Category> threeWrapper = new LambdaQueryChainWrapper<>(this.getBaseMapper());
        // 3.2 查询数据
        // 3.2.1 获取二级类目id
        List<Integer> twoIds = twos.stream().map(Category::getId).collect(Collectors.toList());
        // 3.2.2 获取三级类目（每一个二级类别下的三级类别）
        List<Category> threes = threeWrapper.in(Category::getParentId, twoIds).list();
        // 4 填充数据到categoryDTO
        // 4.1 创建三级类别categoryDTO
        /**
         * json.pasreObject把字符串转换成指定的类别
         * json.toJSONString把指定的类别转换成字符串
         * 每一个都转换，最后tolist
         */
        List<CategoryDTO> threeDTOs = threes.stream()
                .map(three -> JSON.parseObject(JSON.toJSONString(three), CategoryDTO.class))
                .collect(Collectors.toList());
        // 4.2 填充二级类目数据
        /**
         * stream().map()把流中的每个元素转换为另一种形式，产生新流。
         * 先把twos的第一个元素取出，转换为dto类。
         * 再从第三级dto中筛选出parentId为二级类目的id的元素，最后collect(Collectors.toList())
         * filter(Predicate)
         * 对流中的每个元素进行条件判断，保留返回 true 的元素，产生新流。
         * filter也会遍历元素，他会遍历第三级元素parent_id等于当前twodto元素的id然后选出返回结果为true的元素转换成新流
         * 最后tolist转换为集合，到此，第一个第二级元素挂载第三级元素就完成了，而后继续遍历第二个二级元素
         * 有点类似于双层for循环的结构
         */
        List<CategoryDTO> twoDTOs = twos.stream().map(two -> {
            //  category转换成categoryDTO
            CategoryDTO twoDTO = JSON.parseObject(JSON.toJSONString(two), CategoryDTO.class);
            // 筛选出二级类目的三级类目
            List<CategoryDTO> items = threeDTOs.stream().filter(three ->
                    three.getParentId().equals(twoDTO.getId())
            ).collect(Collectors.toList());
            // 填充三级类目数据
            twoDTO.setCategoryList(items);
            return twoDTO;
        }).collect(Collectors.toList());
        // 4.3 填充一级类目数据
        List<CategoryDTO> oneDTOs = ones.stream().map(one -> {
            //  category转换成categoryDTO
            CategoryDTO oneDTO = JSON.parseObject(JSON.toJSONString(one), CategoryDTO.class);
            // 筛选出一级类目的二级类目
            List<CategoryDTO> items =twoDTOs.stream().filter(two ->
                    two.getParentId().equals(oneDTO.getId())
            ).collect(Collectors.toList());
            // 填充二级类目数据
            oneDTO.setCategoryList(items);
            return oneDTO;
        }).collect(Collectors.toList());
        return oneDTOs;
    }

    @Override
    public List<Integer> listAllByParentId(List<Integer> parentId) {
            LambdaQueryChainWrapper<Category> Threewrapper = new LambdaQueryChainWrapper<>(this.baseMapper);
            List<Integer> ids = Threewrapper.in(Category::getParentId, parentId).select(Category::getId).list()
                    .stream().map(category -> category.getId()).collect(Collectors.toList());
            return ids;
        }

    @Override
    public List<Integer> listAllByParentId(Integer parentId) {
        LambdaQueryChainWrapper<Category> wrapper = new LambdaQueryChainWrapper<>(this.baseMapper);
        List<Integer> Threeids = wrapper.eq(Category::getParentId, parentId).select(Category::getId).list()
                .stream().map(category -> category.getId()).collect(Collectors.toList());
        return Threeids;
    }
}

